/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package healthcare.coursework.service;

import healthcare.coursework.model.*;
import healthcare.coursework.util.Utility;
import java.util.Date;
import java.util.List;
import javax.ejb.Stateless;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 *
 * @author Administrator
 */
@Stateless(name = "AppointmentService")
//@WebMethod
//@TransactionManagement(value = TransactionManagementType.CONTAINER)
public class AppointmentServiceImpl implements AppointmentService {

//    @Resource
//    private SessionContext context;
    @PersistenceContext
    EntityManager em;

    //@WebMethod
    public boolean bookDiagnoseAppointment(Long patientId, int serviceId, String username, Date appointTime) {
        try {
            DiagnosesPK key = new DiagnosesPK(patientId, username, serviceId);
            Users user = em.find(Users.class, username);
            Diagnoses diagnose = new Diagnoses(key, Utility.convertDateToTimestamp(appointTime), false);
            diagnose.setUser(user);
            diagnose.setService(em.find(Service.class, serviceId));
            em.persist(diagnose);
            return true;
        } catch (Exception e) {
            System.err.println("Failed to book appointment with doctor!!!");
            return false;
        }
    }

    //@WebMethod
    public List<Diagnoses> listOfDiagnoseAppointments(Long patientId) {
        Query q = em.createQuery("SELECT d FROM Diagnoses d WHERE d.patient.patientId=?1");
        q.setParameter(1, patientId);
        List<Diagnoses> diagnoses = q.getResultList();
//        for (int i = 0; i < diagnoses.size(); i++) {
//            Diagnoses diagnose = diagnoses.get(i);
//            if (diagnose.getService() == null ) {
//                Service service = em.find(Service.class, diagnose.getDiagnosesPK().getServiceId());
//                diagnose.setService(service);
//                System.out.println("Serivce name :"+service.getServiceName());
//                diagnoses.add(i, diagnose);
//            }
//        }
        return diagnoses;
    }

    /**
     * Cancel appointment with doctor
     * @param appointKey
     */
    //@WebMethod
    public void cancelDiagnoseAppointment(DiagnosesPK appointKey) {
        Diagnoses d = em.find(Diagnoses.class, appointKey);
        d.setIsCanceled(true);
        em.merge(d);
    }

    //@WebMethod
    public Diagnoses findDiagnoseAppointment(DiagnosesPK appointKey) {
        Diagnoses diagnose = em.find(Diagnoses.class, appointKey);
        return diagnose;
    }

    //@WebMethod
    public void update(Diagnoses diagnose) {
        em.merge(diagnose);
    }

    //@WebMethod
    public void recover(DiagnosesPK appointKey) {
        Diagnoses diagnose = em.find(Diagnoses.class, appointKey);
        if (diagnose == null) {
            throw new EntityNotFoundException("cannot found this appointment");
        } else {
            diagnose.setIsCanceled(false);
            em.merge(diagnose);
        }
    }

    //@WebMethod
    public void removeForever(DiagnosesPK appointKey) {
        Diagnoses diagnose = em.find(Diagnoses.class, appointKey);
        if (diagnose != null) {
            em.remove(diagnose);
        }
    }

    //@WebMethod
    public void makeRequestForLab(String username, Long resourceId, Long patientId, String testName, Date appointTime) {
        TestSamplesPK pk = new TestSamplesPK(username, resourceId, patientId);
        TestSamples ts = new TestSamples(pk, testName, RequestStatus.pending);
        ts.setPatient(em.find(Patient.class, patientId));
        ts.setFacility(em.find(Facility.class, resourceId));
        ts.setUser(em.find(Users.class, username));
        ts.setTrackedDate(appointTime);
        em.persist(ts);

    }

    //@WebMethod
    public TestSamples findTestSample(TestSamplesPK id) {
        return em.find(TestSamples.class, id);
    }

    public List<TestSamples> listOfRequestLabTesting() {
        Query query = em.createQuery("SELECT t FROM TestSamples t ");
        return query.getResultList();
    }

    public List<TestSamples> listOfAdmittedLabTesting() {
        Query query = em.createQuery("SELECT t FROM TestSamples t WHERE t.requestStatus =?1");
        query.setParameter(1, RequestStatus.admitted);
        return query.getResultList();
    }

    public List<TestSamples> listOfAdmittedLabTesting(String trackCode) {
        Query query = em.createQuery("SELECT t FROM TestSamples t WHERE t.requestStatus =?1 AND t.patient.trackCode=?2");
        query.setParameter(1, RequestStatus.admitted);
        query.setParameter(2, trackCode);
        return query.getResultList();
    }

    //@WebMethod
    public void bookAppointmentForLab(TestSamplesPK pk) {
        TestSamples ts = em.find(TestSamples.class, pk);
        ts.setRequestStatus(RequestStatus.admitted);
        em.merge(ts);
    }

    //@WebMethod
    public void cancelAppointmentForLab(TestSamplesPK pk) {
        TestSamples ts = em.find(TestSamples.class, pk);
        ts.setRequestStatus(RequestStatus.denied);
        em.merge(ts);
    }

    //@WebMethod
    public void updateTestSample(TestSamples sample) {
        em.merge(sample);
    }

    //@WebMethod
    public void removeTestSampleForever(TestSamplesPK appointKey) {
        em.remove(em.find(TestSamples.class, appointKey));
    }

    //@WebMethod
    public void addSampleResult(TestSamplesPK pk, String result) {
        TestSamples ts = em.find(TestSamples.class, pk);
        ts.setSampleResult(result);
        em.merge(ts);
    }

    public List<Service> listOfServices() {
        Query q = em.createQuery("SELECT s FROM Service s WHERE s.isDeleted = 'FALSE'");
        return q.getResultList();
    }
}
